﻿using System;
using System.Linq;
using System.Web.Mvc;
using Autofac;
using Autofac.Integration.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NMock2;
using Vowei.Core.Models;
using Vowei.Web;
using Vowei.Data.Models;
using Vowei.Web.Controllers;
using Vowei.Data;

namespace vowei.test
{   
    [TestClass()]
    public class ProjectControllerTest : TestBase
    {
        [TestMethod()]
        public void PreEditItemTest()
        {
            // 创建的情况
            var target = new ProjectController(VoweiContext, Setting.DefaultFormUser);
            Guid? id = null;
            var actual = target.Edit(id) as ViewResult;

            Assert.IsNotNull(actual.ViewData.Model);
            var project = actual.ViewData.Model as Project;
            Assert.IsNotNull(project);

            Assert.AreNotEqual(Guid.Empty, project.ID);
            Assert.IsTrue(string.IsNullOrEmpty(project.Title));

            using (var context = new VoweiContextImpl())
            {
                var expected = context.Projects.First();
                actual = target.Edit(expected.ID) as ViewResult;

                Assert.IsNotNull(actual.ViewData.Model);
                project = actual.ViewData.Model as Project;
                Assert.IsNotNull(project);
                Assert.AreEqual(expected.ID, project.ID);
                Assert.AreEqual(expected.Title, project.Title);
            }
        }

        [TestMethod()]
        public void PreCreateTest()
        {
            var target = new ProjectController(VoweiContext, Setting.DefaultFormUser);
            var actual = target.Create() as ViewResult;

            Assert.IsNotNull(actual.ViewData.Model);
            var project = actual.ViewData.Model as Project;
            Assert.IsNotNull(project);

            Assert.AreNotEqual(Guid.Empty, project.ID);
            Assert.IsTrue(string.IsNullOrEmpty(project.Title));
        }

        [TestMethod()]
        public void PostCreateTest()
        {
            var target = new ProjectController(VoweiContext, Setting.DefaultFormUser); 
            var expected = new Project()
            {
                Title = "PostCreateTest_Project",
                Owner = "yimin_shi@hotmail.com",
                StartDate = DateTime.Now,
                DueDate = DateTime.Now + TimeSpan.FromDays(30),
                ScmType = "Svn"
            };

            var actual = target.Create(expected);
            Assert.IsNotNull(actual as RedirectToRouteResult);

            // 创建一个新的项目
            expected = new Project()
            {
                Title = "PostCreateTest_Project",
                Owner = "yimin_shi@hotmail.com",
                StartDate = DateTime.Now,
                DueDate = DateTime.Now + TimeSpan.FromDays(30),
                ScmType = "Svn"
            };

            using (var context = new VoweiContextImpl())
            {
                var milestone = new Milestone()
                {
                    Title = "PostCreateTest_Milestone",
                    StartDate = DateTime.Now,
                    DueDate = DateTime.Now + TimeSpan.FromDays(7)
                };
                context.Milestones.Add(milestone);
                context.SaveChanges();

                expected.Children.Add(new Milestone()
                {
                    ID = milestone.ID,
                    Title = milestone.Title
                });
            }

            actual = target.Create(expected);
            Assert.IsNotNull(actual as RedirectToRouteResult);

            using (var context = new VoweiContextImpl())
            {
                var projectFound = context.Projects.Find(expected.ID);
                Assert.IsNotNull(projectFound);

                Assert.AreEqual(expected.Title, projectFound.Title);
                Assert.AreEqual(1, projectFound.Children.Count());
            }
        }

        [TestMethod()]
        public void DetailsBasicTest()
        {
            var target = new ProjectController(VoweiContext, Setting.DefaultFormUser);
            using (var context = new VoweiContextImpl())
            {
                var project = GetDefaultProject(context);
                var actual = target.Details(project.ID);

                Assert.IsTrue(actual is ViewResult);
                var result = actual as ViewResult;

                Assert.IsTrue(result.ViewData.Model is Project);
                Assert.AreEqual(project.ID, ((Project)result.ViewData.Model).ID);
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void DetailsNegativeTest()
        {
            var target = new ProjectController(VoweiContext, Setting.DefaultFormUser);
            target.Details(null);
        }


        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void DetailsNegativeTest1()
        {
            var target = new ProjectController(VoweiContext, Setting.DefaultFormUser);
            target.Details(Guid.Empty);
        }

        [TestMethod()]
        public void PostEditItemNoChildrenTest()
        {
            var mocks = new Mockery();
            var user = mocks.NewMock<IUser>();
            var builder = new ContainerBuilder();
            builder.RegisterInstance(user).As<IUser>();

            var container = builder.Build();
            MvcApplication.ContainerProviderStatic = new ContainerProvider(container);
            Expect.AtLeastOnce.On(user).GetProperty("Email").Will(Return.Value(Setting.DefaultUserName));

            var target = new ProjectController(VoweiContext, Setting.DefaultFormUser);
            Project expected = null;

            try
            {
                using (var context = new VoweiContextImpl())
                {
                    var project = new Project()
                    {
                        Title = "PostEditItemTest_Project",
                        Owner = Setting.DefaultUserName,
                        StartDate = DateTime.Now,
                        DueDate = DateTime.Now + TimeSpan.FromDays(30)
                    };
                    context.Projects.Add(project);
                    context.SaveChanges();

                    expected = new Project();
                    expected.ID = project.ID;
                    expected.ClosedDate = project.ClosedDate;
                    expected.DueDate = project.DueDate;
                    expected.OpenDate = project.OpenDate;
                    expected.Owner = project.Owner;
                    expected.Reporter = project.Reporter;
                    expected.ScmType = project.ScmType;
                    expected.ScmUrl = project.ScmUrl;
                    expected.StartDate = project.StartDate;
                    expected.Title = project.Title;
                }

                expected.Title = "PostEditItemTest_Project_Changed";
                expected.StartDate = new DateTime(2010, 1, 1);
                var result = target.Edit(expected) as RedirectToRouteResult;
                Assert.IsNotNull(result);

                using (var context = new VoweiContextImpl())
                {
                    var project = context.Find<Project>(expected.ID);
                    Assert.AreEqual(expected.Title, project.Title);
                    Assert.AreEqual(expected.StartDate, project.StartDate);
                }
            }
            finally
            {
                MvcApplication.ContainerProviderStatic = null;
            }
        }
    }
}
